package com.cchr.donation;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import com.paypal.exception.ClientActionRequiredException;
import com.paypal.exception.HttpErrorException;
import com.paypal.exception.InvalidCredentialException;
import com.paypal.exception.InvalidResponseDataException;
import com.paypal.exception.MissingCredentialException;
import com.paypal.exception.SSLConfigurationException;
import com.paypal.sdk.exceptions.OAuthException;
import urn.ebay.api.PayPalAPI.CreateRecurringPaymentsProfileReq;
import urn.ebay.api.PayPalAPI.CreateRecurringPaymentsProfileRequestType;
import urn.ebay.api.PayPalAPI.CreateRecurringPaymentsProfileResponseType;
import urn.ebay.api.PayPalAPI.DoExpressCheckoutPaymentReq;
import urn.ebay.api.PayPalAPI.DoExpressCheckoutPaymentRequestType;
import urn.ebay.api.PayPalAPI.DoExpressCheckoutPaymentResponseType;
import urn.ebay.api.PayPalAPI.GetExpressCheckoutDetailsReq;
import urn.ebay.api.PayPalAPI.GetExpressCheckoutDetailsRequestType;
import urn.ebay.api.PayPalAPI.GetExpressCheckoutDetailsResponseType;
import urn.ebay.api.PayPalAPI.PayPalAPIInterfaceServiceService;
import urn.ebay.api.PayPalAPI.SetExpressCheckoutReq;
import urn.ebay.api.PayPalAPI.SetExpressCheckoutRequestType;
import urn.ebay.api.PayPalAPI.SetExpressCheckoutResponseType;
import urn.ebay.apis.CoreComponentTypes.BasicAmountType;
import urn.ebay.apis.eBLBaseComponents.ActivationDetailsType;
import urn.ebay.apis.eBLBaseComponents.AutoBillType;
import urn.ebay.apis.eBLBaseComponents.BillingAgreementDetailsType;
import urn.ebay.apis.eBLBaseComponents.BillingCodeType;
import urn.ebay.apis.eBLBaseComponents.BillingPeriodDetailsType;
import urn.ebay.apis.eBLBaseComponents.BillingPeriodType;
import urn.ebay.apis.eBLBaseComponents.CreateRecurringPaymentsProfileRequestDetailsType;
import urn.ebay.apis.eBLBaseComponents.CurrencyCodeType;
import urn.ebay.apis.eBLBaseComponents.DoExpressCheckoutPaymentRequestDetailsType;
import urn.ebay.apis.eBLBaseComponents.PayerInfoType;
import urn.ebay.apis.eBLBaseComponents.PaymentActionCodeType;
import urn.ebay.apis.eBLBaseComponents.PaymentDetailsItemType;
import urn.ebay.apis.eBLBaseComponents.PaymentDetailsType;
import urn.ebay.apis.eBLBaseComponents.RecurringPaymentsProfileDetailsType;
import urn.ebay.apis.eBLBaseComponents.ScheduleDetailsType;
import urn.ebay.apis.eBLBaseComponents.SetExpressCheckoutRequestDetailsType;

public class PaypalExpressCheckOut {

	public static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    public SetExpressCheckoutResponseType setExpressCheckout(Product product,PayPalAPIInterfaceServiceService service,String returnURL,String cancelURL) throws SSLConfigurationException, InvalidCredentialException, HttpErrorException, InvalidResponseDataException, ClientActionRequiredException, MissingCredentialException, OAuthException, IOException, InterruptedException, ParserConfigurationException, SAXException{
	
	PaymentDetailsType paymentDetails = new PaymentDetailsType();
	paymentDetails.setPaymentAction(PaymentActionCodeType.SALE);
	
	PaymentDetailsItemType donationItem = new PaymentDetailsItemType();
	BasicAmountType amt = new BasicAmountType();
	amt.setCurrencyID(CurrencyCodeType.USD);
	amt.setValue(product.getPrice());
	donationItem.setQuantity(product.getQuantity());
	donationItem.setName(product.getName());
	donationItem.setAmount(amt);
	
	List<PaymentDetailsItemType> lineItems = new ArrayList<PaymentDetailsItemType>();
	lineItems.add(donationItem);
	
	paymentDetails.setPaymentDetailsItem(lineItems);
	
	BasicAmountType orderTotal = new BasicAmountType();
	orderTotal.setCurrencyID(CurrencyCodeType.USD);
	orderTotal.setValue(product.getPrice()); 
	paymentDetails.setOrderTotal(orderTotal);
	
	List<PaymentDetailsType> paymentDetailsList = new ArrayList<PaymentDetailsType>();
	paymentDetailsList.add(paymentDetails);
	
	
	SetExpressCheckoutRequestDetailsType setExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType();
	if(returnURL!=null && returnURL.length()>0){
	    setExpressCheckoutRequestDetails.setReturnURL(returnURL);
	}
	if(cancelURL !=null && cancelURL.length()>0){
	    setExpressCheckoutRequestDetails.setCancelURL(cancelURL);
	}
			
	setExpressCheckoutRequestDetails.setPaymentDetails(paymentDetailsList);

	SetExpressCheckoutRequestType setExpressCheckoutRequest = new SetExpressCheckoutRequestType(setExpressCheckoutRequestDetails);
	setExpressCheckoutRequest.setVersion("104.0");

	SetExpressCheckoutReq setExpressCheckoutReq = new SetExpressCheckoutReq();
	setExpressCheckoutReq.setSetExpressCheckoutRequest(setExpressCheckoutRequest);
	
	SetExpressCheckoutResponseType setExpressCheckoutResponse = service.setExpressCheckout(setExpressCheckoutReq);
	
	return setExpressCheckoutResponse;
    }
    
    public GetExpressCheckoutDetailsResponseType getExpressCheckout(String token,PayPalAPIInterfaceServiceService service) throws SSLConfigurationException, InvalidCredentialException, HttpErrorException, InvalidResponseDataException, ClientActionRequiredException, MissingCredentialException, OAuthException, IOException, InterruptedException, ParserConfigurationException, SAXException{
	
	GetExpressCheckoutDetailsRequestType reqType = new GetExpressCheckoutDetailsRequestType(token);
	
	GetExpressCheckoutDetailsReq req = new GetExpressCheckoutDetailsReq();
	req.setGetExpressCheckoutDetailsRequest(reqType);

        GetExpressCheckoutDetailsResponseType response=  service.getExpressCheckoutDetails(req);;
	
        return response;
    }
    
    public DoExpressCheckoutPaymentResponseType doExpressCheckout(String token,PayPalAPIInterfaceServiceService service,GetExpressCheckoutDetailsResponseType responseGet) throws SSLConfigurationException, InvalidCredentialException, HttpErrorException, InvalidResponseDataException, ClientActionRequiredException, MissingCredentialException, OAuthException, IOException, InterruptedException, ParserConfigurationException, SAXException{
	PayerInfoType payerInfo = responseGet.getGetExpressCheckoutDetailsResponseDetails().getPayerInfo();
	DoExpressCheckoutPaymentRequestDetailsType doExpressCheckoutPaymentRequestDetails = new DoExpressCheckoutPaymentRequestDetailsType();
	
	doExpressCheckoutPaymentRequestDetails.setPaymentDetails(responseGet.getGetExpressCheckoutDetailsResponseDetails().getPaymentDetails());
	doExpressCheckoutPaymentRequestDetails.setToken(token);
	doExpressCheckoutPaymentRequestDetails.setPayerID(payerInfo.getPayerID());
	
	DoExpressCheckoutPaymentRequestType doExpressCheckoutPaymentRequest = new DoExpressCheckoutPaymentRequestType(
		doExpressCheckoutPaymentRequestDetails);
	
	DoExpressCheckoutPaymentReq doExpressCheckoutPaymentReq = new DoExpressCheckoutPaymentReq();
	doExpressCheckoutPaymentReq.setDoExpressCheckoutPaymentRequest(doExpressCheckoutPaymentRequest);
	 
	return service.doExpressCheckoutPayment(doExpressCheckoutPaymentReq);
		
    }
    
    public SetExpressCheckoutResponseType setExpressCheckoutForRecurringPayments(Product product,PayPalAPIInterfaceServiceService service,String returnURL,String cancelURL) throws SSLConfigurationException, InvalidCredentialException, HttpErrorException, InvalidResponseDataException, ClientActionRequiredException, MissingCredentialException, OAuthException, IOException, InterruptedException, ParserConfigurationException, SAXException{
	
	PaymentDetailsType paymentDetails = new PaymentDetailsType();
	paymentDetails.setPaymentAction(PaymentActionCodeType.SALE);
	
	PaymentDetailsItemType item = new PaymentDetailsItemType();
	BasicAmountType amt = new BasicAmountType();
	//PayPal uses 3-character ISO-4217 codes for specifying currencies in fields and variables. 
	amt.setCurrencyID(CurrencyCodeType.USD);
	amt.setValue(product.getPrice());
	item.setQuantity(product.getQuantity());
	item.setName(product.getName());
	item.setAmount(amt);
	
	List<PaymentDetailsItemType> lineItems = new ArrayList<PaymentDetailsItemType>();
	lineItems.add(item);
	
	paymentDetails.setPaymentDetailsItem(lineItems);
	
	BasicAmountType orderTotal = new BasicAmountType();
	orderTotal.setCurrencyID(CurrencyCodeType.USD);
	orderTotal.setValue(product.getPrice()); 
	paymentDetails.setOrderTotal(orderTotal);
	
	List<PaymentDetailsType> paymentDetailsList = new ArrayList<PaymentDetailsType>();
	paymentDetailsList.add(paymentDetails);
	
	BillingAgreementDetailsType billingAgreement = new BillingAgreementDetailsType(BillingCodeType.RECURRINGPAYMENTS);
	billingAgreement.setBillingAgreementDescription(product.getName());
	List<BillingAgreementDetailsType> billList = new ArrayList<BillingAgreementDetailsType>();
	billList.add(billingAgreement);
	
	SetExpressCheckoutRequestDetailsType setExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType();
	if(returnURL!=null && returnURL.length()>0){
	    setExpressCheckoutRequestDetails.setReturnURL(returnURL);
	}
	if(cancelURL !=null && cancelURL.length()>0){
	    setExpressCheckoutRequestDetails.setCancelURL(cancelURL);
	}
	
	setExpressCheckoutRequestDetails.setPaymentDetails(paymentDetailsList);
	setExpressCheckoutRequestDetails.setBillingAgreementDetails(billList);
	
	SetExpressCheckoutRequestType setExpressCheckoutRequest = new SetExpressCheckoutRequestType(setExpressCheckoutRequestDetails);
	setExpressCheckoutRequest.setVersion("104.0");

	SetExpressCheckoutReq setExpressCheckoutReq = new SetExpressCheckoutReq();
	setExpressCheckoutReq.setSetExpressCheckoutRequest(setExpressCheckoutRequest);
	
	SetExpressCheckoutResponseType setExpressCheckoutResponse = service.setExpressCheckout(setExpressCheckoutReq);
	 
	return setExpressCheckoutResponse;
    }
    
    public CreateRecurringPaymentsProfileResponseType createRecurringPaymentsProfile(String token,Product product,PayPalAPIInterfaceServiceService service,int billingCycles) throws SSLConfigurationException, InvalidCredentialException, HttpErrorException, InvalidResponseDataException, ClientActionRequiredException, MissingCredentialException, OAuthException, IOException, InterruptedException, ParserConfigurationException, SAXException{
	
	BasicAmountType basicAmountType= new BasicAmountType(CurrencyCodeType.USD,product.getPrice());
	
	CreateRecurringPaymentsProfileReq req = new CreateRecurringPaymentsProfileReq();
	CreateRecurringPaymentsProfileRequestType reqType = new CreateRecurringPaymentsProfileRequestType();
	
	
	 Calendar calendar=Calendar.getInstance();   
	 calendar.setTime(new Date()); 
	 calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)+12);// add one day
	Date date=  calendar.getTime();
//	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//	RecurringPaymentsProfileDetailsType profileDetails = new RecurringPaymentsProfileDetailsType( format.format(date)+ "T00:00:00:000Z");
	RecurringPaymentsProfileDetailsType profileDetails = new RecurringPaymentsProfileDetailsType( format.format(date));
	profileDetails.setSubscriberName(product.getName());
	
	ScheduleDetailsType scheduleDetails = new ScheduleDetailsType();
	scheduleDetails.setDescription(product.getName());
	scheduleDetails.setMaxFailedPayments(5);
	scheduleDetails.setAutoBillOutstandingAmount(AutoBillType.NOAUTOBILL);
	
//	BasicAmountType activeAmountType= new BasicAmountType(CurrencyCodeType.USD,"0");
//	ActivationDetailsType activationDetails = new ActivationDetailsType(activeAmountType);
//	scheduleDetails.setActivationDetails(activationDetails);
	
	BillingPeriodDetailsType paymentPeriod = new BillingPeriodDetailsType(BillingPeriodType.MONTH, 1, basicAmountType);
	paymentPeriod.setTotalBillingCycles(billingCycles);  // the cycles for bill period
	scheduleDetails.setPaymentPeriod(paymentPeriod);
	
	CreateRecurringPaymentsProfileRequestDetailsType reqDetails = new CreateRecurringPaymentsProfileRequestDetailsType(
		profileDetails, scheduleDetails);
	reqDetails.setToken(token);
	
	reqType.setCreateRecurringPaymentsProfileRequestDetails(reqDetails);
	req.setCreateRecurringPaymentsProfileRequest(reqType);
	
	CreateRecurringPaymentsProfileResponseType resp = service.createRecurringPaymentsProfile(req);
	
	return resp;
    }
}
